﻿#define TODO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.NetworkInformation;
using System.Net;
using System.Net.Sockets;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Diagnostics;



namespace common
{   
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// ilyen üzenetek mennek át a hálózaton
    /// </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    [Serializable]
    public class NetworkMessage
    {
        #region Variables
        //az objektum tipusát tartalmazza
        private Type _objTipus;
        //és itt az adat
        private byte[] _objData;
        #endregion

        #region Properties
        /// <summary>
        /// eltároljuk benne az objektum típusát
        /// </summary>
        public Type objTipus
        {
            get { return _objTipus; }
            set { _objTipus = value; }
        }
        /// <summary>
        /// és itt az adat maga
        /// </summary>
        public byte[] objData
        {
            get { return _objData; }
            set { _objData = value; }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="objtipus">meg kell adni a továbbítandó adat típusát</param>
        /// <param name="data">és az adatot</param>
        public NetworkMessage(Type objtipus, byte[] data)
        {
            _objTipus = objtipus;
            _objData = data;
        }
        #endregion
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// A kliens programok hálózati azonosításához szükséges dolgai
    /// </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    [Serializable]
    public class KliensID
    {
        #region Variables
        private string _gepNev;
        private string _userNev;
        private string _jelszo;
        private int _id;
        private string _ip;
        private bool _belepve;
        #endregion

        #region Constructors
        /// <summary>
        /// def. konstruktor
        /// </summary>
        public KliensID()
        {
            _belepve = false;
        }
        #endregion

        #region Properties
        /// <summary>
        /// a szerver server.Szerver.kliensek listájának kulcs értéke
        /// </summary>
        public int id
        {
            get { return _id; }
            set { _id = value; }
        }
        /// <summary>
        /// a kliens programot használó usert sikeresen authentikálta-e a szerver?
        /// </summary>
        public bool belepve
        {
            get { return _belepve; }
            set { _belepve = value; }
        }
        /// <summary>
        /// a kliensprogramot futtató gép hostneve
        /// </summary>
        public string gepNev
        {
            get { return _gepNev; }
            set { _gepNev = value; }
        }
        /// <summary>
        /// a PEMS-ben használt felhasználói azonosító
        /// </summary>
        public string userNev
        {
            get { return _userNev; }
            set { _userNev = value; }
        }
        /// <summary>
        /// a PEMS-ben használt felhasználóhoz ezt a jelszót adjuk meg
        /// </summary>
        public string jelszo
        {
            get { return _jelszo; }
            set { _jelszo = value; }
        }
        /// <summary>
        /// a kliensprogramot futtató gép ipv4 címe
        /// </summary>
        public string ip
        {
            get { return _ip; }
            set { _ip = value; }
        }
        #endregion

        #region Methods

        #endregion
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// A programok ezen keresztül írják a logot
    /// ha nincs megadva file, a log a Visual Studio output ablakában látszik 
    /// </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public static class Log
    {
        /// <summary>
        /// a log írása
        /// </summary>
        /// <param name="s">ezt írjuk fájlba</param>
        /// <param name="srclineappend">a forráskód sorát hozzáírjuk-e</param>
        public static void logToFile(String s, bool srclineappend)
        {
            StackFrame stackFrame = new StackFrame(1, true);

            string file = Path.GetFileName(stackFrame.GetFileName().ToString());
            int line = stackFrame.GetFileLineNumber();
            if (srclineappend)
                Trace.WriteLine(s + " " + file + ": " + line);
            else
                Trace.WriteLine(s);
            Trace.Flush();
        }
        /// <summary>
        /// Rendelkezünk, hogy a trace fájlba is írjon
        /// a log a futtatjató program (exe) mellett jön létre
        /// </summary>
        /// <param name="logfilename">a logfile neve</param>
        public static void setLogFile(string logfilename)
        {
            TextWriterTraceListener tr = new TextWriterTraceListener(System.IO.File.CreateText(logfilename));
            Debug.Listeners.Add(tr);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// serializálható Dictionary, hogy tudjuk fájlba írni
    /// </summary>
    /// <typeparam name="TKey">TKey</typeparam>
    /// <typeparam name="TValue">TValue</typeparam>
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    [XmlRoot("dictionary")]
    public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
    {
        #region IXmlSerializable Members
        /// <summary>
        /// GetSchema
        /// </summary>
        /// <returns>null</returns>
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }
        /// <summary>
        /// ReadXml
        /// </summary>
        /// <param name="reader">XmlReader param</param>
        public void ReadXml(System.Xml.XmlReader reader)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
            
            bool wasEmpty = reader.IsEmptyElement;
            reader.Read();

            if (wasEmpty)
                return;

            while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
            {
                reader.ReadStartElement("item");
                reader.ReadStartElement("key");

                TKey key = (TKey)keySerializer.Deserialize(reader);
                reader.ReadEndElement();
                reader.ReadStartElement("value");

                TValue value = (TValue)valueSerializer.Deserialize(reader);
                reader.ReadEndElement();

                this.Add(key, value);
                reader.ReadEndElement();

                reader.MoveToContent();
            }
            reader.ReadEndElement();
        }


        /// <summary>
        /// WriteXml
        /// </summary>
        /// <param name="writer">XmlWriter param</param>
        public void WriteXml(System.Xml.XmlWriter writer)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

            foreach (TKey key in this.Keys)
            {
                writer.WriteStartElement("item");
                writer.WriteStartElement("key");

                keySerializer.Serialize(writer, key);
                writer.WriteEndElement();

                writer.WriteStartElement("value");
                TValue value = this[key];

                valueSerializer.Serialize(writer, value);
                writer.WriteEndElement();

                writer.WriteEndElement();
            }
        }
        #endregion
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// Ember, akikből származik pl. az Admin, Tanar, Tanulo
    /// </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    [Serializable]
    [XmlInclude(typeof(Admin))]
    [XmlInclude(typeof(Tanar))]
    public abstract class Ember
    {
        #region Variables
        private string _userName;
        private string _password;
        private bool _active;
        #endregion

        #region Properties
        /// <summary>
        /// a felhasználó PEMS id-je
        /// </summary>
        [XmlElement("UserName")]
        public string userName{
            get { return _userName; }
            set { _userName = value; }
        }
        /// <summary>
        /// a felhasználó PEMS jelszava
        /// </summary>
        [XmlElement("Jelszo")]
        public string password
        {
            get { return _password; }
            set { _password=value; }
        }
        /// <summary>
        /// a PEMS-ben aktíválva van-e a felhasználó
        /// </summary>
        [XmlElement("Aktiv_allapot")]
        public bool active
        {
            get { return _active; }
            set { _active = value; }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// default constructor, a serializálás miatt kell
        /// </summary>
        public Ember()
        {
          
        }
        /// <summary>
        /// konstruktor név megadással
        /// </summary>
        /// <param name="username">a felhasználónév</param>
        public Ember(string username)
        {
            _userName = username;
        }
        #endregion
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// Tanár
    /// </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    [Serializable]
    public class Tanar : Ember
    {
        #region Variables
        private int _t1;
        #endregion

        #region Constructors
        /// <summary>
        /// default constructor, a serializálás miatt kell
        /// </summary>
        public Tanar()
            : base()
        {

        }
        /// <summary>
        /// konstruktor név megadással
        /// </summary>
        /// <param name="usernev">a felhasználónév</param>
        public Tanar(string usernev)
            : base(usernev)
        {

        }
        #endregion

        #region Properties
        /// <summary>
        /// csak tanárnaknak létező property, teszt célból
        /// </summary>
        [XmlElement("csak_Tanarnak_letezo_prop")]
        public int tanarProprety
        {
            get { return _t1; }
            set { _t1 = value; }
        }
        #endregion
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// Admin
    /// </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    [Serializable]
    public class Admin:Ember
    {
        #region Variables
        private int _a1;
        #endregion

        #region Constructors
        /// <summary>
        /// default constructor, a serializálás miatt kell
        /// </summary>
        public Admin()
            : base()
        {

        }
        /// <summary>
        /// konstruktor név megadással
        /// </summary>
        /// <param name="usernev">a felhasználónév</param>
        public Admin(string usernev):base(usernev)
        {
            
        }
        #endregion

        #region Properties
        /// <summary>
        /// csak adminnak_létező property, teszt célból
        /// </summary>
        [XmlElement("csak_adminnak_letezo_prop")]
        public int adminProprety
        {
            get { return _a1; }
            set { _a1 = value; }
        }
        #endregion

        #region Methods
        
        
        /// <summary>
        /// tud aktíválni felhasználót
        /// </summary>
        /// <param name="uID">PEMS username, ezt a felhasználót aktíválja</param>
        public void activateUser(string uID){
        
        }

        #endregion
    }
}
